package com.bao.auth.server.biz.service.common.impl;

import cn.hutool.core.util.StrUtil;
import com.bao.auth.entity.auth.User;
import com.bao.auth.entity.common.LoginLog;
import com.bao.auth.server.biz.dao.common.LoginLogMapper;
import com.bao.auth.server.biz.service.auth.UserService;
import com.bao.auth.server.biz.service.common.LoginLogService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import eu.bitwalker.useragentutils.Browser;
import eu.bitwalker.useragentutils.OperatingSystem;
import eu.bitwalker.useragentutils.UserAgent;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
@Slf4j
public class LoginLogServiceImpl extends ServiceImpl<LoginLogMapper, LoginLog> implements LoginLogService {

    @Autowired
    private UserService userService;

    private final static String[] BROWSER = new String[]{
            "Chrome", "Firefox", "Microsoft Edge", "Safari", "Opera"
    };
    private final static String[] OPERATING_SYSTEM = new String[]{
            "Android", "Linux", "Mac OS X", "Ubuntu", "Windows 10", "Windows 8", "Windows 7", "Windows XP", "Windows Vista"
    };

    /**
     * 返回操作系统名，不存在就返回传入的 字符串
     * @param operatingSysstem
     * @return
     */
    private static String simplifyOperatingSystem(String operatingSysstem) {
        for (String s : OPERATING_SYSTEM) {
            if (StrUtil.containsIgnoreCase(operatingSysstem, s)) {
                return s;
            }
        }
        return operatingSysstem;
    }

    /**
     * 返回浏览器， 不存在就返回传入字符串
     * @param browser
     * @return
     */
    private static String simplifyBrowser(String browser) {
        for (String b : BROWSER){
            if (StrUtil.containsIgnoreCase(browser, b)){
                return b;
            }
        }
        return browser;
    }
    
    
    @Override
    public LoginLog save(String account, String ua, String ip, String location, String description) {
        User user = userService.getByAccount(account);
        UserAgent userAgent = UserAgent.parseUserAgentString(ua);
        Browser browser = userAgent.getBrowser();
        OperatingSystem operatingSystem = userAgent.getOperatingSystem();
        LoginLog loginLog = LoginLog.builder()
                                    .account(account)
                                    .location(location)
                                    .loginDate(LocalDate.now())
                                    .description(description)
                                    .requestIp(ip)
                                    .ua(ua)
                                    .userName(account)
                                    .browser(simplifyBrowser(browser.getName()))
                                    .browserVersion(userAgent.getBrowserVersion().getVersion())
                                    .operatingSystem(simplifyOperatingSystem(operatingSystem.getName()))
                                    .build();
        if (user != null) {
            loginLog.setUserId(user.getId()).setUserName(user.getName());
        }
        super.save(loginLog);
        return loginLog;
    }

    @Override
    public Long findTotalVisitCount() {
        return baseMapper.findTotalVisitCount();
    }

    @Override
    public Long findTodayVisitCount() {
        return baseMapper.findTodayVisitCount(LocalDate.now());
    }

    @Override
    public Long findTodayIp() {
        return baseMapper.findTodayIp(LocalDate.now());
    }

    @Override
    public List<Map<String, Object>> findLastTenDaysVisitCount(String account) {
        LocalDate tenDays = LocalDate.now().plusDays(-9);
        return baseMapper.findLastTenDaysVisitCount(tenDays, account);
    }

    @Override
    public List<Map<String, Object>> findByBrowser() {
        return baseMapper.findByBrowser();
    }

    @Override
    public List<Map<String, Object>> findByOperatingSystem() {
        return baseMapper.findByOperatingSystem();
    }
}
